import datetime
import streamlit as st
import pandas as pd
import plotly.express as px
import numpy as np
import yaml
from yaml.loader import SafeLoader
import streamlit_authenticator as stauth
import time
import math
import plotly.graph_objects as go

st.set_page_config(
    page_title="储能收益计算系统",
    page_icon="🔋",
    layout="wide"
)

def calculate_count(time):
    from datetime import datetime, time as dt_time
    # 从00:15开始计数为1
    start_time = dt_time(0, 15)
    # 计算时间差（以分钟为单位）
    minutes_diff = (time.hour * 60 + time.minute) - (start_time.hour * 60 + start_time.minute)
    # 每15分钟为一个单位
    return (minutes_diff // 15) + 1


def max_profit(prices, capacity):
    prices = prices.reset_index(drop=True)
    n = len(prices)  # 时间点数量
    dp = np.zeros((n + 1, capacity + 1))
    traceback = -np.ones((n + 1, capacity + 1), dtype=int)
    idle, charge, discharge = 0, 1, 2
    investment = 0
    for j in range(capacity - 1, -1, -1):
        investment = investment - prices[node][capacity - j] * reserve_capacity / capacity
        dp[0][j] = investment

    progress_text = "计算最佳方案中，请稍后。"
    my_bar = st.progress(0, text=progress_text)
    # 动态规划转移方程
    for i in range(1, n + 1):
        for j in range(capacity + 1):
            # 不进行充放电，直接从上一个状态继承最大收益
            dp[i][j] = dp[i - 1][j]
            traceback[i][j] = idle

            # 如果可以充电并且剩余容量允许
            if j < capacity:
                potential_gain_charge = dp[i - 1][j + 1] - (prices[node][i - 1]) * reserve_capacity / capacity
                if potential_gain_charge > dp[i][j]:
                    dp[i][j] = potential_gain_charge
                    traceback[i][j] = charge

            # 如果可以放电并且当前有电可放
            if j > 0:
                potential_gain_discharge = dp[i - 1][j - 1] + (
                    prices[node][i - 1]) * reserve_capacity * efficiency / capacity 
                if potential_gain_discharge > dp[i][j]:
                    dp[i][j] = potential_gain_discharge
                    traceback[i][j] = discharge
        if i % (int(n / 100) + 1) == 0:
            my_bar.progress(int(i / (n / 100)), text=progress_text)
    my_bar.progress(100, text="计算完成")
    time.sleep(1)
    my_bar.empty()
    i, j = n, capacity  # 从最后一个时间点和最大容量开始回溯
    operations_sequence = []  # 用于存储操作序列
    while i > 0:
        operation = traceback[i][j]
        if operation == charge:
            operations_sequence.append(charge)
        elif operation == discharge:
            operations_sequence.append(discharge)
        else:  # idle
            operations_sequence.append(idle)

        # 根据操作更新i和j的值以进行下一步回溯
        if operation == charge:
            j += 1  # 如果是充电，则容量增加
        elif operation == discharge:
            j -= 1  # 如果是放电，则容量减少

        i -= 1  # 总是向之前的时间点移动

    # 由于序列是反向生成的（从结束到开始），我们需要将其反转以符合时间顺序
    operations_sequence.reverse()
    return max(dp[n]), operations_sequence  # 返回最大收益和操作序列


def max_profit_more(prices, capacity):
    cooldown = capacity
    prices = prices.reset_index(drop=True)
    n = len(prices)  # 时间点数量
    dp = np.zeros((n + 1, 2))
    traceback = -np.ones((n + 1, 2), dtype=int)
    idle, charge, discharge = 0, 1, 2

    def price(i, o):
        average_price = 0
        for k in range(capacity):
            if i < n - capacity:
                average_price += prices[o][i - 1 + k]
        return average_price / capacity

    dp[0][0] = - prices[node][1] * reserve_capacity

    # 动态规划转移方程
    for i in range(1, n + 1):
        cooldown -= 1  # 每次迭代减少冷却计数器

        for j in [0, 1]:
            dp[i][j] = dp[i - 1][j]
            traceback[i][j] = idle

            # 跳过冷却期内的充放电操作
            if cooldown > 0:
                continue

            # 如果可以充电并且剩余容量允许
            if j < 1:
                potential_gain_charge = dp[i - 1][j + 1] - price(i, node) * reserve_capacity
                if potential_gain_charge > dp[i][j]:
                    dp[i][j] = potential_gain_charge
                    traceback[i][j] = charge
                    cooldown = capacity  # 充电后重置冷却计数器

            # 如果可以放电并且当前有电可放
            if j > 0:
                potential_gain_discharge = dp[i - 1][j - 1] + (
                    price(i, node)) * reserve_capacity * efficiency 
                if potential_gain_discharge > dp[i][j]:
                    dp[i][j] = potential_gain_discharge
                    traceback[i][j] = discharge
                    cooldown = capacity  # 放电后重置冷却计数器

    i, j = n, 1  # 从最后一个时间点和最大容量开始回溯
    operations_sequence = []  # 用于存储操作序列
    while i > 0:
        operation = traceback[i][j]
        if operation == charge:
            operations_sequence.append(charge)
        elif operation == discharge:
            operations_sequence.append(discharge)
        else:  # idle
            operations_sequence.append(idle)

        # 根据操作更新i和j的值以进行下一步回溯
        if operation == charge:
            j += 1  # 如果是充电，则容量增加
        elif operation == discharge:
            j -= 1  # 如果是放电，则容量减少

        i -= 1  # 总是向之前的时间点移动
    # 由于序列是反向生成的（从结束到开始），我们需要将其反转以符合时间顺序
    operations_sequence.reverse()
    return max(dp[n]), operations_sequence  # 返回最大收益和操作序列


def calculate_daily_gain(energy, group, time_1, time_2, time_3, time_4, time_5, time_6, time_7):
    max_gain = 0
    energy_time = 0
    prices = group.reset_index(drop=True)
    date_values = prices["日期"][0].date()
    area_values = group[area].values
    area_date = group["日期+时刻"].values
    node_values = group[node].values
    node_date = group["日期+时刻"].values
    min_start_index = 0
    max_start_index = 0
    for op in range(1, energy + 1):
        min_sum = float('inf')
        min_index = 0
        for i in range(len(node_values) - op - 1):  # 减15是因为窗口大小为16
            current_sum = sum(node_values[i:i + op])
            if current_sum < min_sum:
                min_sum = current_sum
                min_index = i
        min_sum = min_sum / op

        max_sum = 0
        max_index = 0
        for i in range(min_index + op, len(node_values) - op - 1):  # 减15是因为窗口大小为16
            current_sum = sum(node_values[i:i + op])
            if current_sum > max_sum:
                max_sum = current_sum
                max_index = i
        max_sum = max_sum / op

        daily_gain = reserve_speed / 4 * op * efficiency * max_sum - reserve_speed / 4 * op * min_sum
        if daily_gain > max_gain:
            max_gain = daily_gain
            max_start_index = max_index
            min_start_index = min_index
            energy_time = op

    for i in range(energy_time):
        time_4.append(node_date[min_start_index + i])
        time_5.append(node_values[min_start_index + i])
        time_6.append(node_date[max_start_index + i])
        time_7.append(node_values[max_start_index + i])

    if max_gain > 0:
        time_1.append(date_values)
        time_2.append(energy_time * reserve_speed / 4 * efficiency)
        time_3.append(energy_time * reserve_speed / 4)
        return max_gain
    else:
        time_1.append(date_values)
        time_2.append(0)
        time_3.append(0)
        return 0


def max_daily_profit(prices, capacity, op, time_1, time_2, time_3, time_4, time_5, time_6, time_7, time_8):
    # time_2.clear()
    # time_1.clear()
    prices = prices.reset_index(drop=True)
    daily_profit = 0
    charge_time = 0
    discharge_time = 0
    date_values = prices["日期"][0].date()
    for i in range(len(prices)):
        if prices[op][i] == 1:
            daily_profit -= prices[node][i] * reserve_capacity / capacity
            charge_time += 1
            time_4.append(prices["日期+时刻"][i])
            time_5.append(prices[node][i])
        elif prices[op][i] == 2:
            daily_profit += prices[node][i] * reserve_capacity * efficiency / capacity 
            discharge_time += 1
            time_6.append(prices["日期+时刻"][i])
            time_7.append(prices[node][i])
        # elif prices[op][i] == 0:
        # charge_discharge_time.append(f'{prices["日期+时刻"][i]} 空闲：15分钟')
    time_8.append(f'充电{charge_time}次，放电{discharge_time}次')
    time_1.append(date_values)
    time_2.append(discharge_time * reserve_capacity * efficiency / capacity)
    time_3.append(charge_time * reserve_capacity / capacity)
    return daily_profit


with open('config.yaml', encoding='utf-8') as file:
    config = yaml.load(file, Loader=SafeLoader)

authenticator = stauth.Authenticate(
    config['credentials'],
    config['cookie']['name'],
    config['cookie']['key'],
    config['cookie']['expiry_days'],
    config['pre-authorized']
)
authenticator.login()

if st.session_state["authentication_status"]:
    authenticator.logout()
    st.write(f'欢迎 *{st.session_state["name"]}*')
    if "uploaded_file" in st.session_state:
        processed_file = st.session_state.uploaded_file
        if processed_file is not None:
            df = processed_file

            st.title("区间数据")
            # 输入条件
            st.sidebar.subheader('输入条件')
            start_date = st.sidebar.date_input("开始日期", datetime.date(2024, 1, 1))
            end_date = st.sidebar.date_input("结束日期", datetime.date(2024, 12, 31))
            df["日期"] = pd.to_datetime(df["日期"])
            mask = (df["日期"].dt.date >= start_date) & (df["日期"].dt.date <= end_date)
            filtered_df = df[mask]
            mask = (df["日期"].dt.date >= datetime.date(2023, 6, 1)) & (
                    df["日期"].dt.date <= datetime.date(2024, 5, 31))
            filtered_df_23 = df[mask]
            names = list(df.keys())
            node_names = names[5:]
            all_names = names[3:]
            area = st.sidebar.selectbox("选择区域", (names[3], names[4]))
            city = st.sidebar.selectbox(
                "选择地区",
                ("包头市", "鄂尔多斯市", "阿拉善盟", "锡林郭勒盟", "呼和浩特市", "乌海市", "巴彦淖尔市", "乌兰察布市","薛家湾"),
                index=None,
                # placeholder="Select contact method...",
            )
            if city == "包头市":
                node = st.sidebar.selectbox("选择节点", names[5:37])
            elif city == "鄂尔多斯市":
                node = st.sidebar.selectbox("选择节点", names[37:73])
            elif city == "阿拉善盟":
                node = st.sidebar.selectbox("选择节点", names[73:88])
            elif city == "锡林郭勒盟":
                node = st.sidebar.selectbox("选择节点", names[88:109])
            elif city == "呼和浩特市":
                node = st.sidebar.selectbox("选择节点", names[109:137])
            elif city == "乌海市":
                node = st.sidebar.selectbox("选择节点", names[137:151])
            elif city == "巴彦淖尔市":
                node = st.sidebar.selectbox("选择节点", names[151:176])
            elif city == "乌兰察布市":
                node = st.sidebar.selectbox("选择节点", names[176:213])
            elif city == "薛家湾":
                node = st.sidebar.selectbox("选择节点", names[213:223])
            else:
                node = st.sidebar.selectbox("选择节点", node_names)
            # option = {
            #     "电网侧储能": 16,
            #     "电源侧储能": 8
            # }
            # reserve_type = st.sidebar.selectbox("储能类型",
            #                                     list(option.keys()),
            #                                     # index=None,
            #                                     # placeholder="选择储能类型...",
            #                                     )
            option = st.sidebar.number_input("储能时长(h)", value=4, placeholder="输入储能时长..")
            efficiency = st.sidebar.number_input("储能效率", value=0.85, placeholder="输入储能效率...")
            reserve_speed = st.sidebar.number_input("储能功率(MW)", value=100, placeholder="输入储能功率...")
            reserve_capacity = reserve_speed * option
            # tariff = st.sidebar.number_input("输配电价(元/kWh)", value=0.0455, format="%f")
            # other = st.sidebar.number_input("政府性资金及附加(元/kWh)", value=0.022425, format="%f")
            # others = tariff + other

            # 电价数据
            with st.container(border=True):
                st.subheader('电价数据', divider=True)
                df_show = df
                df_show.index = df['日期+时刻']

                if st.checkbox('显示数据'):
                    st.dataframe(df_show, use_container_width=True)
                with st.container(border=True):
                    options1 = st.multiselect("选择", all_names, [area, node])
                    fig = px.line(filtered_df, x="日期+时刻", y=options1, title="电价数据", template='plotly_white')
                    fig.update_traces(textposition="bottom right")
                    fig.update_layout(
                        xaxis_title=None,
                        yaxis_title="电价（元/MWh）",
                        margin=dict(b=150),  # 调整边距
                        height=600
                    )
                    fig.update_xaxes(
                        tickformat="%Y-%m-%d"  # 设置日期格式为年-月-日
                    )
                    st.plotly_chart(fig, theme="streamlit", use_container_width=True)

                    # 分时价格曲线图
                    month_mapping = {
                        'January': '一月',
                        'February': '二月',
                        'March': '三月',
                        'April': '四月',
                        'May': '五月',
                        'June': '六月',
                        'July': '七月',
                        'August': '八月',
                        'September': '九月',
                        'October': '十月',
                        'November': '十一月',
                        'December': '十二月'
                    }
                with st.container(border=True):
                    tab1, tab2, tab3 = st.tabs(["2023.6-2024.5区域数据", "自选节点数据", "自选区域数据"])
                    filtered_df_23['月份'] = pd.to_datetime(filtered_df_23['日期'])
                    filtered_df_23['时刻'] = pd.to_datetime(filtered_df_23['时刻']).dt.strftime('%H').replace('00',
                                                                                                              '24')
                    filtered_df['月份'] = pd.to_datetime(filtered_df['日期'])
                    filtered_df['时刻'] = pd.to_datetime(filtered_df['时刻']).dt.strftime('%H').replace('00', '24')
                    with tab1:
                        month_hourly_avg = \
                            filtered_df_23.groupby([filtered_df_23['月份'].dt.to_period('M'), '时刻'])[
                                area].mean().reset_index()
                        month_hourly_avg['月份'] = month_hourly_avg['月份']
                        fig = px.line(month_hourly_avg, x='时刻', y=area, color='月份',
                                      title='分时价格曲线',
                                      labels={
                                          area: '元/MWh'})
                        fig.update_xaxes(nticks=24)
                        fig.update_layout(
                            xaxis_title=None,
                            legend=dict(font=dict(size=9))
                        )
                        st.plotly_chart(fig)
                    with tab2:
                        month_hourly_avg = filtered_df.groupby([filtered_df['月份'].dt.to_period('M'), '时刻'])[
                            node].mean().reset_index()
                        month_hourly_avg['月份'] = month_hourly_avg['月份']
                        fig = px.line(month_hourly_avg, x='时刻', y=node, color='月份',
                                      title='分时价格曲线',
                                      labels={
                                          area: '元/MWh'})
                        fig.update_xaxes(nticks=24)
                        fig.update_layout(
                            xaxis_title=None,
                            legend=dict(font=dict(size=9))
                        )
                        st.plotly_chart(fig)
                    with tab3:
                        month_hourly_avg = filtered_df.groupby([filtered_df['月份'].dt.to_period('M'), '时刻'])[
                            area].mean().reset_index()
                        month_hourly_avg['月份'] = month_hourly_avg['月份']
                        fig = px.line(month_hourly_avg, x='时刻', y=area, color='月份',
                                      title='分时价格曲线',
                                      labels={
                                          area: '元/MWh'})
                        fig.update_xaxes(nticks=24)
                        fig.update_layout(
                            xaxis_title=None,
                            legend=dict(font=dict(size=9))
                        )
                        st.plotly_chart(fig)

                    # 现货市场价格分布区间
                with st.container(border=True):

                    bins = [-float('inf'), 0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000,
                            1100, 1200, 1300, 1400, 1500, float('inf')]  # 最后一个边界为无穷大
                    # 定义区间标签
                    labels = ['<1', '1-100', '100-200', '200-300', '300-400', '400-500',
                              '500-600', '600-700', '700-800', '800-900', '900-1000',
                              '1000-1100', '1100-1200', '1200-1300', '1300-1400', '1400-1500', '>1500']
                    tab1, tab2, tab3 = st.tabs(["2023.6-2024.5区域数据", "自选节点数据", "自选区域数据"])
                    with tab1:
                        # 继续执行你的操作
                        df['数量区间'] = pd.cut(filtered_df_23[area], bins=bins, labels=labels, include_lowest=True)

                        # 计算每个区间的频率
                        interval_counts = df['数量区间'].value_counts().sort_index() / 4

                        # 将Series转换为DataFrame以便于绘图
                        interval_df = interval_counts.reset_index()
                        interval_df.columns = ['数量区间', '频数']

                        # 使用plotly创建柱状图
                        fig = px.bar(interval_df, x='数量区间', y='频数',
                                     title='现货市场价格分布区间',
                                     labels={'数量区间': '元/MWh', '频数': '（小时）'})
                        # 显示图表
                        st.plotly_chart(fig)
                    with tab2:
                        df['数量区间'] = pd.cut(filtered_df[node], bins=bins, labels=labels, include_lowest=True)
                        # 计算每个区间的频率
                        interval_counts = df['数量区间'].value_counts().sort_index() / 4

                        # 将Series转换为DataFrame以便于绘图
                        interval_df = interval_counts.reset_index()
                        interval_df.columns = ['数量区间', '频数']

                        # 使用plotly创建柱状图
                        fig = px.bar(interval_df, x='数量区间', y='频数',
                                     title='现货市场价格分布区间',
                                     labels={'数量区间': '元/MWh', '频数': '（小时）'})
                        # 显示图表
                        st.plotly_chart(fig)
                    with tab3:
                        df['数量区间'] = pd.cut(filtered_df[area], bins=bins, labels=labels, include_lowest=True)
                        # 计算每个区间的频率
                        interval_counts = df['数量区间'].value_counts().sort_index() / 4

                        # 将Series转换为DataFrame以便于绘图
                        interval_df = interval_counts.reset_index()
                        interval_df.columns = ['数量区间', '频数']

                        # 使用plotly创建柱状图
                        fig = px.bar(interval_df, x='数量区间', y='频数',
                                     title='现货市场价格分布区间',
                                     labels={'数量区间': '元/MWh', '频数': '（小时）'})
                        # 显示图表
                        st.plotly_chart(fig)
                with st.container(border=True):
                    tab1, tab2, tab3 = st.tabs(["2023.6-2024.5区域数据", "自选节点数据", "自选区域数据"])
                    with tab1:
                        daily_prices = filtered_df_23.groupby('日期')[area].agg(['min', 'max']).reset_index()
                        daily_prices['diff'] = daily_prices['max'] - daily_prices['min']
                        max_diff_ceil = math.ceil(max(daily_prices['diff']))
                        thresholds = range(1, max_diff_ceil)
                        result = pd.DataFrame({'Threshold': thresholds})
                        for th in thresholds:
                            result.loc[result['Threshold'] == th, '天数'] = (daily_prices['diff'] > th).sum()
                        result = result.reset_index(drop=True)
                        result = result.iloc[:-1]
                        fig = px.line(result, x="天数", template='plotly_white', title='分时最大峰谷差分布曲线', )
                        fig.update_xaxes(nticks=30)
                        fig.update_layout(
                            xaxis_title="（天）",
                            yaxis_title="（元/MWh）",
                        )
                        st.plotly_chart(fig)
                    with tab2:
                        daily_prices = filtered_df.groupby('日期')[node].agg(['min', 'max']).reset_index()
                        daily_prices['diff'] = daily_prices['max'] - daily_prices['min']
                        max_diff_ceil = math.ceil(max(daily_prices['diff']))
                        thresholds = range(1, max_diff_ceil)
                        result = pd.DataFrame({'Threshold': thresholds})
                        for th in thresholds:
                            result.loc[result['Threshold'] == th, '天数'] = (daily_prices['diff'] > th).sum()
                        result = result.reset_index(drop=True)
                        result = result.iloc[:-1]
                        fig = px.line(result, x="天数", template='plotly_white', title='分时最大峰谷差分布曲线', )
                        fig.update_xaxes(nticks=30)
                        fig.update_layout(
                            xaxis_title="（天）",
                            yaxis_title="（元/MWh）",
                        )
                        st.plotly_chart(fig)
                    with tab3:
                        daily_prices = filtered_df.groupby('日期')[area].agg(['min', 'max']).reset_index()
                        daily_prices['diff'] = daily_prices['max'] - daily_prices['min']
                        max_diff_ceil = math.ceil(max(daily_prices['diff']))
                        thresholds = range(1, max_diff_ceil)
                        result = pd.DataFrame({'Threshold': thresholds})
                        for th in thresholds:
                            result.loc[result['Threshold'] == th, '天数'] = (daily_prices['diff'] > th).sum()
                        result = result.reset_index(drop=True)
                        result = result.iloc[:-1]
                        fig = px.line(result, x="天数", template='plotly_white', title='分时最大峰谷差分布曲线', )
                        fig.update_xaxes(nticks=30)
                        fig.update_layout(
                            xaxis_title="（天）",
                            yaxis_title="（元/MWh）",
                        )
                        st.plotly_chart(fig)
                        # fig = go.Figure(data=go.Scatter(
                        #     x=result['天数'],
                        #     y=result['Threshold'],
                        #     mode='markers',
                        #     marker=dict(size=2, color='rgb(150, 200, 250)'),
                        # ))
                        #
                        # # 设置图表标题和坐标轴标签
                        # fig.update_layout(
                        #     title='分时最大峰谷差分布曲线',
                        #     xaxis_title="（天）",
                        #     yaxis_title="（元/MWh）",
                        # )
                        # fig.update_xaxes(nticks=30)
                        # # 在Streamlit应用中显示图表
                        # st.plotly_chart(fig)

            with st.container(border=True):
                tab1, tab2, tab3 = st.tabs(["一充一放", "多充多放", "随充随放"])
                gains1 = []
                gains2 = []
                gains3 = []
                with tab1:
                    st.subheader('逐日收益', divider=True)
                    expander = st.expander("查看计算方法")
                    expander.write(
                        '''
                        每天都不固定时间（最长为2小时或4小时，以收益最大为标准）充放电一次，如果收益为负，则放弃充放电
                        ''')
                    tab1_1 = []
                    tab1_2 = []
                    tab1_3 = []
                    tab1_4 = []
                    tab1_5 = []
                    tab1_6 = []
                    tab1_7 = []
                    daily_gains = filtered_df.groupby(filtered_df['日期'].dt.date).apply(
                        lambda group: calculate_daily_gain(option * 4, group, tab1_1, tab1_2, tab1_3, tab1_4,
                                                           tab1_5, tab1_6, tab1_7))

                    st.write("区间总收益：", round(daily_gains.sum() / 10000, 4), "（万元）")
                    gains1 = round(daily_gains.sum() / 10000, 4)
                    daily_gains_df = daily_gains.reset_index()
                    daily_gains_df.columns = ['日期', '收益（元）']
                    fig = px.line(daily_gains_df, x="日期", y="收益（元）", markers=True, title="逐日收益")
                    fig.update_traces(textposition="bottom right")
                    fig.update_xaxes(
                        tickformat="%Y-%m-%d"  # 设置日期格式为年-月-日
                    )
                    fig.update_layout(
                        xaxis_title=None
                    )
                    st.plotly_chart(fig, theme="streamlit", use_container_width=True)

                    st.subheader('区间总放电量', divider=True)
                    st.write("区间总放电量：", sum(tab1_2), "（MWh）")
                    st.write("每日平均放电量：", round(sum(tab1_2) / len(tab1_2), 1), "（MWh）")
                    st.write("弃电天数：", tab1_2.count(0))
                    tab1_1 = pd.DataFrame({
                        '日期': tab1_1,
                        '放电量（MWh）': tab1_2,
                        '充电量（MWh）': tab1_3
                    })
                    tab1_1 = pd.merge(tab1_1, daily_gains_df[['日期', '收益（元）']], on='日期', how='left')

                    # 将收益转换为万元并添加到新的列中
                    tab1_1['收益（万元）'] = tab1_1['收益（元）'] / 10000

                    # 删除临时的收益（元）列
                    tab1_1.drop(columns=['收益（元）'], inplace=True)
                    st.dataframe(tab1_1)

                    if tab1_4:
                        tab1_4 = pd.DataFrame(tab1_4)
                        tab1_4["充电电价"] = tab1_5
                        tab1_4.columns = ['充电时间', '充电电价']
                        tab1_4.index += 1
                        st.dataframe(tab1_4)
                    if tab1_6:
                        tab1_6 = pd.DataFrame(tab1_6)
                        tab1_6["放电电价"] = tab1_7
                        tab1_6.columns = ['放电时间', '放电电价']
                        tab1_6.index += 1
                        st.dataframe(tab1_6)
                with tab2:
                    st.subheader('逐日收益', divider=True)
                    expander = st.expander("查看计算方法")
                    expander.write(
                        '''
                        每次充放电都以最大时间（4小时或2小时）为单位，采取最适合的充放电策略使得收益最大
                        ''')

                    tab2_1 = []
                    tab2_2 = []
                    tab2_3 = []
                    tab2_4 = []
                    tab2_5 = []
                    tab2_6 = []
                    tab2_7 = []
                    tab2_8 = []
                    max_profit_value, operations = max_profit_more(filtered_df, option * 4)
                    st.write("区间总收益：", round(max_profit_value / 10000, 4), "（万元）")
                    gains2 = round(max_profit_value.sum() / 10000, 4)
                    # 逐日收益
                    filtered_df.insert(loc=len(filtered_df.columns), column='op1', value=operations)
                    max_profit_value = filtered_df.groupby(filtered_df['日期'].dt.date).apply(
                        lambda group: max_daily_profit(group, 1, "op1", tab2_1, tab2_2, tab2_3,
                                                       tab2_4, tab2_5,
                                                       tab2_6, tab2_7, tab2_8)
                    )
                    tab2_1 = pd.DataFrame(tab2_1)
                    tab2_1["放电量（MWh）"] = tab2_2
                    tab2_1["充电量（MWh）"] = tab2_3
                    tab2_1["充放电次数"] = tab2_8
                    tab2_1.columns = ['日期', '放电量（MWh）', '充电量（MWh）', '充放电次数']
                    tab2_1.index += 1

                    max_profit_value = max_profit_value.reset_index()
                    max_profit_value.columns = ['日期', '收益（元）']

                    fig = px.line(max_profit_value, x="日期", y="收益（元）", markers=True, title="逐日收益")
                    fig.update_traces(textposition="bottom right")
                    fig.update_xaxes(
                        tickformat="%Y-%m-%d"  # 设置日期格式为年-月-日
                    )
                    fig.update_layout(
                        xaxis_title=None
                    )
                    st.plotly_chart(fig, theme="streamlit", use_container_width=True)
                    st.subheader('区间总放电量', divider=True)
                    st.write("区间总放电量：", tab2_1['放电量（MWh）'].sum(), "（MWh）")
                    st.write("每日平均放电量：", round(tab2_1['放电量（MWh）'].mean(), 1), "（MWh）")
                    fig = px.line(tab2_1, x="日期", y="放电量（MWh）", markers=True, title="放电量")
                    fig.update_xaxes(
                        tickformat="%Y-%m-%d"  # 设置日期格式为年-月-日
                    )
                    fig.update_layout(
                        xaxis_title=None
                    )
                    st.plotly_chart(fig, theme="streamlit", use_container_width=True)
                    st.dataframe(tab2_1)

                    if tab2_4:  # 如果 tab2_4 不为空
                        tab2_4 = pd.DataFrame(tab2_4)
                        tab2_4["充电电价"] = tab2_5
                        tab2_4.columns = ['充电时间', '充电电价']
                        tab2_4.index += 1
                        st.dataframe(tab2_4)

                    if tab2_6:  # 如果 tab2_6 不为空
                        tab2_6 = pd.DataFrame(tab2_6)
                        tab2_6["放电电价"] = tab2_7
                        tab2_6.columns = ['放电时间', '放电电价']
                        tab2_6.index += 1
                        st.dataframe(tab2_6)

                with tab3:
                    # 区间总收益动态规划算法
                    st.subheader('逐日收益', divider=True)
                    expander = st.expander("查看计算方法")
                    expander.write(
                        '''
                        每次充放电都以最小时间为单位（15分钟），采取最适合的充放电策略使得收益最大
                        ''')
                    tab3_1 = []
                    tab3_2 = []
                    tab3_3 = []
                    tab3_4 = []
                    tab3_5 = []
                    tab3_6 = []
                    tab3_7 = []
                    tab3_8 = []
                    max_profit_value, operations = max_profit(filtered_df, option * 4)

                    st.write("区间总收益：", round(max_profit_value / 10000, 4), "（万元）")
                    gains3 = round(max_profit_value.sum() / 10000, 4)
                    # 逐日收益
                    filtered_df.insert(loc=len(filtered_df.columns), column='op', value=operations)

                    max_profit_value = filtered_df.groupby(filtered_df['日期'].dt.date).apply(
                        lambda group: max_daily_profit(group, option * 4, 'op', tab3_1, tab3_2, tab3_3,
                                                       tab3_4, tab3_5, tab3_6, tab3_7, tab3_8)
                    )
                    tab3_1 = pd.DataFrame(tab3_1)
                    tab3_1["放电量（MWh）"] = tab3_2
                    tab3_1["充电量（MWh）"] = tab3_3
                    tab3_1["充放电次数"] = tab3_8
                    tab3_1.columns = ['日期', '放电量（MWh）', '充电量（MWh）', '充放电次数']
                    tab3_1.index += 1

                    max_profit_value = max_profit_value.reset_index()
                    max_profit_value.columns = ['日期', '收益（元）']

                    fig = px.line(max_profit_value, x="日期", y="收益（元）", markers=True, title="逐日收益")
                    fig.update_traces(textposition="bottom right")
                    fig.update_xaxes(
                        tickformat="%Y-%m-%d"  # 设置日期格式为年-月-日
                    )
                    fig.update_layout(
                        xaxis_title=None
                    )
                    st.plotly_chart(fig, theme="streamlit", use_container_width=True)
                    st.subheader('区间总放电量', divider=True)
                    st.write("区间总放电量：", tab3_1['放电量（MWh）'].sum(), "（MWh）")
                    st.write("每日平均放电量：", round(tab3_1['放电量（MWh）'].mean(), 1), "（MWh）")
                    fig = px.line(tab3_1, x="日期", y="放电量（MWh）", markers=True, title="放电量")
                    fig.update_xaxes(
                        tickformat="%Y-%m-%d"  # 设置日期格式为年-月-日
                    )
                    fig.update_layout(
                        xaxis_title=None
                    )
                    st.plotly_chart(fig, theme="streamlit", use_container_width=True)
                    st.dataframe(tab3_1)

                    if tab3_4:
                        from datetime import datetime, time as dt_time

                        tab3_4 = [datetime.strptime(date_str,  '%Y-%m-%d %H:%M') for date_str in tab3_4]

                        # 创建DataFrame
                        tab3_4 = pd.DataFrame(tab3_4, columns=['DateTime'])
                        tab3_4["充电电价"] = tab3_5

                        # 提取时间部分并应用函数计算Count列

                        tab3_4['Count'] = tab3_4['DateTime'].apply(calculate_count)
                        tab3_4.columns = ['充电时间', '充电电价', '节点']
                        tab3_4.index += 1
                        st.dataframe(tab3_4)
                        fig = px.line(tab3_4, x="充电时间", y="充电电价")
                        st.plotly_chart(fig, theme="streamlit", use_container_width=True)
                    if tab3_6:
                        from datetime import datetime, time as dt_time

                        tab3_6 = [datetime.strptime(date_str,  '%Y-%m-%d %H:%M') for date_str in tab3_6]

                        tab3_6 = pd.DataFrame(tab3_6, columns=['DateTime'])
                        tab3_6["放电电价"] = tab3_7
                        tab3_6['Count'] = tab3_6['DateTime'].apply(calculate_count)
                        tab3_6.columns = ['放电时间', '放电电价', '节点']
                        tab3_6.index += 1
                        st.dataframe(tab3_6)
                        fig = px.line(tab3_6, x="放电时间", y="放电电价")
                        st.plotly_chart(fig, theme="streamlit", use_container_width=True)
            # 逐日充放电最大价差
            with st.container(border=True):
                st.subheader('逐日充放电最大价差', divider=True)
                daily_diffs = filtered_df.groupby(filtered_df['日期'].dt.date).apply(
                    lambda group: group[node].max() - group[node].min()
                )
                st.write("平均充放电价差：", round(daily_diffs.mean(), 1), '（元/MWh）')

                # 示例数据 - 你可以根据自己的需求替换这部分数据
                data = {
                    '节点名称': [node, node, node],
                    '储能规模': [f'{reserve_speed} * {option}h', f'{reserve_speed} * {option}h', f'{reserve_speed} * {option}h'],
                    '充电策略': ['一充一放', '多充多放', '随充随放'],
                    '区间收益（万元）':[gains1,gains2,gains3],
                    '区间总放电量（MWh）':[sum(tab1_2),sum(tab2_2),sum(tab3_2)],
                    '每日平均放电量（MWh）':[round(tab1_1['放电量（MWh）'].mean(), 1),round(tab2_1['放电量（MWh）'].mean(), 1),round(tab3_1['放电量（MWh）'].mean(), 1)],
                    '弃电天数':[tab1_2.count(0),0,0],
                    '平均充放电最大价差（元/MWh）':[round(daily_diffs.mean(), 1),round(daily_diffs.mean(), 1),round(daily_diffs.mean(), 1)]
                }

                df = pd.DataFrame(data)
                df.index += 1
                # 显示DataFrame
                st.write(df)

                
                daily_diffs_df = daily_diffs.reset_index()
                daily_diffs_df.columns = ['日期', '差价（元/MWh）']
                fig = px.line(daily_diffs_df, x="日期", y="差价（元/MWh）", title="逐日充放电最大价差")
                fig.update_traces(textposition="bottom right")
                fig.update_xaxes(
                    tickformat="%Y-%m-%d"  # 设置日期格式为年-月-日
                )
                fig.update_layout(
                    xaxis_title=None
                )
                st.plotly_chart(fig, theme="streamlit", use_container_width=True)
                st.dataframe(daily_diffs_df)

            # 节点、区域逐日平均数据
            with st.container(border=True):
                st.subheader('逐日平均数据', divider=True)
                options2 = st.multiselect("选择区域节点", all_names, [area, node])
                daily = filtered_df.groupby(filtered_df['日期'].dt.date).apply(
                    lambda group: group[options2].mean()
                )
                daily_df = daily.reset_index()
                fig = px.line(daily_df, x="日期", y=options2, title="逐日平均数据", template='plotly_white')
                fig.update_traces(textposition="bottom right")
                fig.update_layout(
                    xaxis_title=None,
                    yaxis_title="电价（元/MWh）",
                )
                fig.update_xaxes(
                    tickformat="%Y-%m-%d"  # 设置日期格式为年-月-日
                )
                st.plotly_chart(fig, theme="streamlit", use_container_width=True)

            with st.container(border=True):

                st.subheader('节点数据汇总', divider=True)
                city = st.selectbox(
                    "选择城市",
                    ("包头市", "鄂尔多斯市", "阿拉善盟", "锡林郭勒盟", "呼和浩特市", "乌海市", "巴彦淖尔市",
                     "乌兰察布市","薛家湾"),
                    index=None,
                    # placeholder="Select contact method...",
                )

                if st.button("计算"):
                    tab4_1 = []
                    tab4_2 = []
                    tab4_3 = []
                    tab4_4 = []
                    tab4_5 = []
                    tab4_6 = []
                    tab4_7 = []
                    tab4_8 = []
                    tab4_9 = []
                    tab4_10 = []
                    tab4_11 = []
                    node_temp = node
                    if city == "包头市":
                        range_to_process = range(5, 37)
                    elif city == "鄂尔多斯市":
                        range_to_process = range(37, 73)
                    elif city == "阿拉善盟":
                        range_to_process = range(73, 88)
                    elif city == "锡林郭勒盟":
                        range_to_process = range(88, 109)
                    elif city == "呼和浩特市":
                        range_to_process = range(109, 137)
                    elif city == "乌海市":
                        range_to_process = range(137, 151)
                    elif city == "巴彦淖尔市":
                        range_to_process = range(151, 176)
                    elif city == "乌兰察布市":
                        range_to_process = range(176, 213)
                    elif city == "薛家湾":
                        range_to_process = range(213, 223)
                    for i in range_to_process:
                        tab4_1.clear()
                        tab4_2.clear()
                        tab4_3.clear()
                        node = names[i]
                        tab4_10.append(names[i])
                        max_profit_value, operations = max_profit_more(filtered_df, option * 4)

                        tab4_9.append(round(max_profit_value / 10000, 4))
                        # 逐日收益
                        filtered_df.insert(loc=len(filtered_df.columns), column=i, value=operations)
                        max_profit_value = filtered_df.groupby(filtered_df['日期'].dt.date).apply(
                            lambda group: max_daily_profit(group, option * 4, 'op', tab4_1, tab4_2, tab4_3,
                                                           tab4_4, tab4_5, tab4_6, tab4_7, tab4_8)
                        )
                        tab4_11.append(sum(tab4_2))

                    tab4_10 = pd.DataFrame(tab4_10)
                    tab4_10["区间总收益"] = tab4_9
                    tab4_10["区间总放电量"] = tab4_11
                    tab4_10.columns = ['节点', '区间总收益(万元)', '区间总放电量(MWh)']

                    tab4_10 = tab4_10.sort_values(by='区间总收益(万元)', ascending=False)
                    tab4_10 = tab4_10.reset_index(drop=True)
                    tab4_10.index += 1
                    fig = px.bar(tab4_10, x="节点", y='区间总收益(万元)', title="节点汇总",
                                 barmode="group")

                    fig.update_layout(
                        xaxis_title=None
                    )
                    st.plotly_chart(fig, theme="streamlit", use_container_width=True)
                    st.dataframe(tab4_10)
                    node = node_temp


elif st.session_state["authentication_status"] is False:
    st.error('Username/password is incorrect')
elif st.session_state["authentication_status"] is None:
    st.warning('Please enter your username and password')
